﻿#ifndef IPAYPLAYINTERFACE_H_
#define IPAYPLAYINTERFACE_H_

#include <iostream>

namespace zl
{
/*!
  payplat error code
  */
enum EPayError
{
    EPayError_Success = 0x00,         // success
    EPayError_Failed = 0x01,          // failed
    EPayError_NetworkError = 0x02,    // network issue
    EPayError_ORDERIDMISMATCH = 0x03, // order id mismatch
    EPayError_Timeout = 0x04,         // request timeout

    EPayError_ParseXMLError = 0x20, // parse xml error
    EPayError_400 = 0x40,           // http 400
    EPayError_404 = 0x44,           // http 404
    EPayError_500 = 0x50,           // http 500
    EPayError_502 = 0x52,           // http 502

    EPayError_Unknow = 0xFF // unknow error
};

/*!
  pay request type
  */
enum EPayRequestType
{
    EPayRequestTypeCreate = 0x01, // create request
    EPayRequestTypeCheck = 0x02,  // check request
    EPayRequestTypeFind = 0x03,   //find order
};

/*!
  Payplat configuration
  */
typedef struct PayplatConfig
{
    std::string auth_name;
    std::string auth_id;
    std::string site_name;
    std::string site_id;
    std::string corp_name;
    std::string corp_id;
    std::string plat_url;

    int32_t timeout;
} PayplatConfig;

/*!
  pay request
  */
typedef struct PayRequest
{
    std::string order_id;
    std::string pay_type;
    std::string currency_type;
    std::string fee_type;
    std::string total_fee;
    std::string trade_no;
    std::string prepay_id;

    int type;

    PayRequest() : order_id(""),
                   pay_type(""),
                   currency_type("CNY"), 
                   fee_type("01"), 
                   total_fee("0"), 
                   trade_no(""), 
                   type(zl::EPayRequestTypeCreate) {}
} PayRequest;

/*!
  pay reply
  */
typedef struct PayReply
{
    /* zhead */
    std::string retcode;
    std::string retmsg;
    std::string totnum;
    std::string curnum;

    /* zbody */
    std::string img_url;
    std::string order_id;
    std::string out_trade_no;
    std::string total_fee;
    std::string pay_type;
    std::string product_id;
    std::string pay_state;
    std::string limit_time;
    std::string pay_time;
    std::string resp_time;
    std::string prepay_id;

    int type;
} PayReply;

/*!
  PayInterface callback class
  */
class IPayplatObserver
{
  public:
    IPayplatObserver() {}
    virtual ~IPayplatObserver() {}

    virtual void PayplatReply(zl::PayReply rep, int32_t code = zl::EPayError_Success) {}
};

/*!
  PayInterface
  */
class IPayplatInterface
{
  public:
    IPayplatInterface() {}
    virtual ~IPayplatInterface() {}

    virtual int32_t Initialize(const PayplatConfig &config, IPayplatObserver *obs = nullptr) = 0;
    virtual void Uninitialize() = 0;
    virtual int32_t EnableOneCode(bool flag) = 0;
    virtual int32_t FindOrder(const PayRequest &req) = 0;
    virtual int32_t CreateOrder(const PayRequest &req) = 0;
    virtual int32_t CheckOrder(const PayRequest &req) = 0;
    virtual int32_t GetQRCode(const std::string &url, char **buf, int32_t &size) = 0;
};

IPayplatInterface *GetPayplatInterface();
void ReleasePayplatInterface(IPayplatInterface *ptr);

} // namespace zl
#endif // IPAYPLAYINTERFACE_H
